﻿using FluentMigrator.Builders.Create;
using FrameworkCore.Migrations.Data;
using System.ComponentModel.DataAnnotations.Schema;
using System.Reflection;

namespace FrameworkCore.Extensions;

public static class MigrationExpressions
{
    public static string GetTableName(this Type type)
    {
        return CommonHelper.GetAttribute<TableAttribute>(type).Name;
    }

    public static string GetColumnName(this Type type, string propertyName)
    {
        PropertyInfo property = type.GetProperty(propertyName) ?? throw new Exception($"{type}迁移异常，{propertyName}字段未找到");

        var attribute = property.GetCustomAttribute<ColumnAttribute>();
        if (attribute != null)
        {
            return attribute.Name!;
        }

        return property.Name;
    }

    public static string ColumnNameFor<T>(string propertyName)
    {
        return typeof(T).GetColumnName(propertyName);
    }

    public static string TableNameFor<T>()
    {
        return typeof(T).GetTableName();
    }

    public static void CreateTableForTEntity<TEntity>(ICreateExpressionRoot createExpression)
    {
        createExpression
           .Table(TableNameFor<TEntity>())
           .WithColumn(typeof(TEntity).GetColumnName(nameof(IEntity<long>.Id)))
           .AsInt64().PrimaryKey().WithColumnDescription("主键")
           .WithColumn(nameof(BaseEntity.Sort)).AsInt32().Nullable().WithColumnDescription("排序")
           .WithColumn(nameof(BaseEntity.Description)).AsString(500).Nullable().WithColumnDescription("描述");
    }

    public static void CreateTableAndBaseAuditableEntityFor<TEntity>(ICreateExpressionRoot createExpression) where TEntity : BaseAuditableEntity
    {
        createExpression
           .Table(TableNameFor<TEntity>())
           .WithColumn(typeof(TEntity).GetColumnName(nameof(IEntity<long>.Id)))
           .AsInt64().PrimaryKey().WithColumnDescription("主键")
           .WithColumn(nameof(BaseAuditableEntity.Sort)).AsInt32().Nullable().WithColumnDescription("排序")
           .WithColumn(nameof(BaseAuditableEntity.Description)).AsString(500).Nullable().WithColumnDescription("描述")
           .WithColumn(nameof(BaseAuditableEntity.Created)).AsDateTime().Nullable().WithDefaultValue(DateTime.Now).WithColumnDescription("创建时间")
           .WithColumn(nameof(BaseAuditableEntity.CreatedBy)).AsString(100).Nullable().WithColumnDescription("创建者")
           .WithColumn(nameof(BaseAuditableEntity.Updated)).AsDateTime().Nullable().WithColumnDescription("修改时间")
           .WithColumn(nameof(BaseAuditableEntity.UpdatedBy)).AsString(100).Nullable().WithColumnDescription("修改者");
    }

    public static void CreateTableAndBaseAuditableAndSoftDeletedEntityFor<TEntity>(ICreateExpressionRoot createExpression) where TEntity : BaseAuditableAndSoftDeletedEntity
    {
        createExpression
           .Table(TableNameFor<TEntity>())
           .WithColumn(typeof(TEntity).GetColumnName(nameof(IEntity<long>.Id)))
           .AsInt64().PrimaryKey().WithColumnDescription("主键")
           .WithColumn(nameof(BaseAuditableAndSoftDeletedEntity.Sort)).AsInt32().Nullable().WithColumnDescription("排序")
           .WithColumn(nameof(BaseAuditableAndSoftDeletedEntity.Description)).AsString(500).Nullable().WithColumnDescription("描述")
           .WithColumn(nameof(BaseAuditableAndSoftDeletedEntity.Created)).AsDateTime().Nullable().WithDefaultValue(DateTime.Now).WithColumnDescription("创建时间")
           .WithColumn(nameof(BaseAuditableAndSoftDeletedEntity.CreatedBy)).AsString(100).Nullable().WithColumnDescription("创建者")
           .WithColumn(nameof(BaseAuditableAndSoftDeletedEntity.Updated)).AsDateTime().Nullable().WithColumnDescription("修改时间")
           .WithColumn(nameof(BaseAuditableAndSoftDeletedEntity.UpdatedBy)).AsString(100).Nullable().WithColumnDescription("修改者")
           .WithColumn(nameof(BaseAuditableAndSoftDeletedEntity.Deleted)).AsDateTime().Nullable().WithColumnDescription("删除时间")
           .WithColumn(nameof(BaseAuditableAndSoftDeletedEntity.DeletedBy)).AsString(100).Nullable().WithColumnDescription("删除者");
    }
}
